﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using InvestmentIntelligence.DbModel.CustomModels;
using InvestmentIntelligence.DbModel.Models;

namespace InvestmentIntelligence.Data.Repository
{
    public interface ITimeSeriesUpdatableRepository : ISeriesRepository, ITimeSerieRepository
    {
        /// <summary>
        ///     Save list of Time series
        /// </summary>
        /// <param name="list"></param>
        void AddMany(IEnumerable<TimeSerie> list);
            
        void Merge(IEnumerable<TimeSerie> toList);
    }

    public interface ITimeSerieRepository 
    {
        /// <summary>
        ///     Return list of TimeSerie for security
        /// </summary>
        /// <param name="securityId">Security id</param>
        /// <param name="startDate">TimeSerie start date (when null then ignore)</param>
        /// <param name="endDate">TimeSerie start date (when null then ignore)</param>
        /// <returns></returns>
        //List<T> GetList<T>(Func<IQueryable<TimeSerie>, IEnumerable<T>> f, int securityId);

        List<T> GetList<T>(Func<IQueryable<TimeSerie>, IEnumerable<T>> f, int securityId, DateTime? startDate=null, DateTime? endDate=null);


        /// <summary>
        ///     return TimeSerie by securityId and date
        /// </summary>
        /// <param name="securityId">Security id</param>
        /// <param name="date">TimeSerire date</param>
        /// <returns></returns>
        TimeSerie Get(int securityId, DateTime date);

        /// <summary>
        /// return StockReturn for securities and date
        /// </summary>
        /// <param name="securityIds"></param>
        /// <param name="minDate"></param>
        /// <returns></returns>
        List<SecurityStockReturn> GetSecurityStockReturns(IEnumerable<int> securityIds, DateTime minDate);

        //ToDo: Cover method with test after merge
        IDictionary<int, DateTime> GetMaxDatePerSecurities(IEnumerable<int> securities);


        T Get<T>(Func<IQueryable<TimeSerie>, T> f);
        Dictionary<int, int> GetSecurityPricePointsPairs(IEnumerable<int> securityIds);
        Dictionary<int, int> GetSecurityPricePointsPairs();

        List<T> GetList<T>(Func<IQueryable<TimeSerie>, IEnumerable<T>> f);

        Expression<Func<TimeSerie, bool>> GetQueryExpression(List<int> securityIds, DateTime? startDate, DateTime? endDate);
        
        List<int> GetDistinctSecurityIds();
    }
}